{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "raw_mimetype": "text/restructuredtext"
   },
   "source": [
    ".. _nb_interface_results:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Result"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "After an algorithm has been executed a result object is returned. In the following, single- and multi-objective runs with and without constraints are shown and the corresponding `Result` object is explained:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "from pymoo.algorithms.soo.nonconvex.ga import GA\n",
    "from pymoo.problems import get_problem\n",
    "from pymoo.optimize import minimize\n",
    "\n",
    "\n",
    "problem = get_problem(\"sphere\")\n",
    "algorithm = GA(pop_size=5)\n",
    "res = minimize(problem,\n",
    "               algorithm,\n",
    "               ('n_gen', 30),\n",
    "               seed=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "After an algorithm has been executed, a result object is returned. In the following, single- and multi-objective runs with and without constraints are shown, and the corresponding `Result` object is explained:\n",
    "\n",
    "In this single-objective optimization problem, there exists a single best solution that was found. \n",
    "The result directly contains the best-found values in the corresponding spaces. \n",
    "\n",
    "- `res.X`: Design space values are \n",
    "- `res.F`: Objective spaces values\n",
    "- `res.G`: Constraint values\n",
    "- `res.CV`: Aggregated constraint violation\n",
    "- `res.algorithm`: Algorithm object which has been iterated over\n",
    "- `res.opt`: The solutions as a `Population` object.\n",
    "- `res.pop`: The final Population\n",
    "- `res.history`: The history of the algorithm. (only if `save_history` has been enabled during the algorithm initialization)\n",
    "- `res.exec_time`: The time required to run the algorithm\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "res.X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "res.F"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "res.G"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "res.CV"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "res.algorithm"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "pop = res.pop"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The values from the final population can be extracted by using the `get` method. The population object is used internally and store information for each individual. The `get` method allows returning vectors or matrices based on the provided properties."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "pop.get(\"X\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "pop.get(\"F\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this run, the problem did not have any constraints, and `res.G` evaluated to `None`.\n",
    "Also, note that `res.CV` will always be set to `0`, no matter if the problem has constraints or not."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let us consider a problem that has, in fact, constraints:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "problem = get_problem(\"g1\")\n",
    "algorithm = GA(pop_size=5)\n",
    "res = minimize(problem,\n",
    "               algorithm,\n",
    "               ('n_gen', 5),\n",
    "               verbose=True,\n",
    "               seed=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "res.X, res.F, res.G, res.CV"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here, the algorithm was not able to find any feasible solution in 5 generations. Therefore, all values contained in the results are equals to `None`. If the least feasible solution should be returned when no feasible solution was found, the flag `return_least_infeasible` can be enabled:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "problem = get_problem(\"g1\")\n",
    "algorithm = GA(pop_size=5)\n",
    "res = minimize(problem,\n",
    "               algorithm,\n",
    "               ('n_gen', 5),\n",
    "               verbose=True,\n",
    "               return_least_infeasible=True,\n",
    "               seed=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "res.X, res.F, res.G, res.CV"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We have made this design decision, because an infeasible solution can often not be considered as a solution\n",
    "of the optimization problem. Therefore, having a solution equals to `None` indicates the fact no feasible solution has been found."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If the problem has multiple objectives, the result object has the same structure but `res.X`, `res.F`, `res .G`, `res.CV` is a set \n",
    "of non-dominated solutions instead of a single one."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "from pymoo.algorithms.moo.nsga2 import NSGA2\n",
    "\n",
    "problem = get_problem(\"zdt2\")\n",
    "algorithm = NSGA2()\n",
    "res = minimize(problem,\n",
    "               algorithm,\n",
    "               ('n_gen', 10),\n",
    "               seed=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "res.F"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
